package com.mvc.business.service;

import java.util.Date;
import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.mvc.business.model.Purchase;
import com.mvc.business.model.PurchaseItem;
import com.mvc.business.model.Schedule;
import com.mvc.finance.model.BankStatementItem;
import com.mvc.finance.service.BankStatementItemManager;
import com.mvc.framework.model.Auditable;
import com.mvc.framework.service.BaseService;

@Service
public class PurchaseItemManager extends BaseService<PurchaseItem, Integer> {

	private static final Logger	     LOGGER	= Logger.getLogger(PurchaseItemManager.class);

	@Autowired
	private PurchaseManager	         purchaseManager;

	@Autowired
	private ScheduleManager	         scheduleManager;

	@Autowired
	private BankStatementItemManager	bankStatementItemManager;

	@Autowired
	private OrderAssociatedManager	 orderAssociatedManager;

	public List<PurchaseItem> getPurchaseItemsByPurchaseId(int purchaseId) {
		PurchaseItem example = new PurchaseItem();
		example.setPurchaseId(purchaseId);
		example.setRecStatus(Auditable.REC_STATUS_VALID);
		return getHibernateTemplate().findByExample(example);
	}

	public void deleteByPackingId(int purchaseId) {
		deleteByWhere("purchaseId = " + purchaseId);
	}

	public void saveOrderItem(PurchaseItem orderItem, String operation) throws Exception {
		if (operation.equals("del")) {
			super.delete(orderItem.getId());
		} else if (operation.equals("add")) {
			orderItem.setId(null);
			super.save(orderItem);
		} else if (operation.equals("edit")) {
			super.save(orderItem);
		}
		Purchase order = purchaseManager.getByObjectId(orderItem.getPurchaseId());
		order.setTotal(getTotal(orderItem.getPurchaseId()));
		purchaseManager.save(order);
	}

	public Double getTotal(int orderId) {
		List<PurchaseItem> orderItems = getPurchaseItemsByPurchaseId(orderId);
		Double total = 0D;
		for (PurchaseItem orderItem : orderItems) {
			total += orderItem.getQuantity() * orderItem.getUnitPrice();
		}
		return total;
	}

	public void updatePurchaseId(Integer oldOrderId, Integer newOrderId) {
		Session session = getHibernateTemplate().getSessionFactory().getCurrentSession();
		Query query = session.createQuery("update " + PurchaseItem.class.getName() + " set purchaseId = " + newOrderId
		        + " where purchaseId = " + oldOrderId);
		query.executeUpdate();
	}

	public int importToSchedule(Integer[] purchaseIds, Schedule example) {
		int total = 0;
		for (Integer purchaseId : purchaseIds) {
			Purchase purchase = purchaseManager.getObject(purchaseId);
			List<Schedule> imported = scheduleManager.getSchedulesByPurchaseId(purchaseId);
			if (purchase.getPurchaseItems().size() != imported.size()) {
				for (PurchaseItem item : purchase.getPurchaseItems()) {
					boolean needImport = true;
					for (Schedule schedule : imported) {
						if (schedule.getPurchaseItemId().equals(item.getObjectId())) {
							needImport = false;
							break;
						}
					}
					if (needImport) {
						try {
							Schedule schedule = new Schedule();
							schedule.setPurchaseId(purchaseId);
							schedule.setSupplierId(purchase.getSupplierId());
							schedule.setName(item.getName());
							schedule.setEnglishName(item.getEnglishName());
							schedule.setQuantity(item.getQuantity());
							schedule.setFinished(false);
							schedule.setPurchaseItemId(item.getObjectId());
							schedule.setCustomerPurchaseNo(item.getCustomerPurchaseNo());
							schedule.setGenerateDate(new Date());
							schedule.setUnit(item.getUnit());
							schedule.setCompanyId(purchase.getCompanyId());
							schedule.setFileDate(example.getFileDate());
							schedule.setBluePaperDate(example.getBluePaperDate());
							schedule.setConfirmProduceDate(example.getConfirmProduceDate());

							schedule.setSampleDate(example.getSampleDate());
							schedule.setConfirmSampleDate(example.getConfirmSampleDate());

							schedule.setBoxMarkDate(example.getBoxMarkDate());
							schedule.setCloseDate(example.getCloseDate());
							schedule.setSendDate(example.getSendDate());

							scheduleManager.save(schedule);
							total++;
						} catch (Exception e) {
							LOGGER.error("importToSchedule", e);
						}
					}
				}
			}
		}
		return total;
	}

	public int importToBankStatement(Integer[] purchaseIds, Integer bankStatementId) {
		int total = 0;
		for (Integer purchaseId : purchaseIds) {
			Purchase purchase = purchaseManager.getObject(purchaseId);
			for (PurchaseItem item : purchase.getPurchaseItems()) {
				Double packed = bankStatementItemManager.getTotalQuantityOfPurchaseItem(item.getObjectId());
				if (packed == null || item.getQuantity() > packed) {
					try {
						BankStatementItem schedule = new BankStatementItem();
						schedule.setBankStatementId(bankStatementId);
						schedule.setName(item.getName());
						schedule.setEnglishName(item.getEnglishName());
						schedule.setQuantity(item.getQuantity() - (packed == null ? 0 : packed));
						schedule.setUnitPrice(item.getUnitPrice());
						schedule.setProductNo("");
						schedule.setUnit(item.getUnit());
						schedule.setPurchaseItemId(item.getObjectId());
						bankStatementItemManager.save(schedule);
						total++;
					} catch (Exception e) {
						LOGGER.error("importToBankStatement", e);
					}
				}
			}
		}
		if (total > 0) {
			orderAssociatedManager.saveBankStatementPurchases(bankStatementId);
		}
		return total;
	}

}
